// @include "../code/Browser.js"
// @include "../code/Type.js"
// @include "../code/String.js"
// @include "../code/Array.js"
// @include "../code/Extend.js"
// @include "../code/Listener.js"
// @include "Css.js"
// @include "Dom.js"
// @include "Tween.js"
// @include "../extend/Debug.js"
/**
 * @fileOverview dom动画渲染工具
 * 
 * @version qinglan_animate 1.0
 * @static
 * @author wxq wxqqh@qq.com
 */
/**
 * 命名空间
 * 
 * @namespace
 * @type Object
 */
window.qinglan = window.qinglan || {};
/**
 * dom动画渲染工具
 * 
 * @type Function
 */
qinglan.Animate = function (id, styleMap, duration,option) {
	
	option = qinglan.Extend.simple({
			delay : 0,
			equal : qinglan.Tween.Quadratic.easeInOut,
			frameRate : 20
		},option,1);
	
	this.id = id ;
	this.ele = $g(id);
	this.duration = duration;
	this.listener = new qinglan.Listener(null,this);
	
	var map =  qinglan.Css.formatStyle(styleMap);
	this.styleMap = map.style;
	this.styleMapLen= map.len;
	
	this.delay =option.delay;
	this.equal = option.equal;
	
	this._data={};
	this._data.nowTime = 0;
	this._data.ispush = false;
	this._data.isPlay = false;
	this.init();

};
/**
 * 动画初始化
 * 
 * @function
 * @public
 */
qinglan.Animate.prototype.init = function() {
	this.duration -= this._data.nowTime; 
	
	var sub = {};
	var begin = {};
	
	for (var s in this.styleMap) { //缓存动画之前所有的差值
		begin[s] = qinglan.Css.get(this.ele, s) || 0;
		sub[s] =  this.styleMap[s].val - begin[s] ;
	}
	this._data.sub = sub;
	this._data.begin = begin;
	
};
/**
 * 动画播放
 * 
 * @function
 * @public
 */
qinglan.Animate.prototype.play = function() {
	var self = this ;
	if(self._data.isPlay){return;}
	if( self.delay ) {
		setTimeout(function(){self.play();}, self.delay);
		self.delay = 0;
	}
	var finishCount = 0;
	var defaultCallBack = function(){
		if(++finishCount == self.styleMapLen){
			self.listener.notify('finish');
		}
	};
	self.interval = this._change(self,self.styleMap,defaultCallBack);
	self._data.isPlay = true;
	self.listener.notify('play');
};
/**
 * 动画停止
 * 改方法会停止动画的渲染，停止之后不能恢复
 * 
 * @function
 * @public
 */
qinglan.Animate.prototype.stop = function(){
	clearInterval(this.interval);
	this._data.isPlay = false;
	this.listener.notify('stop');
};
/**
 * 动画暂停
 * 调用该方法之后动画会暂停，状态会保存，如果想继续可以使用restart方法
 * @see qinglan.Animate.prototype.restart
 * 
 * @function
 * @public
 */
qinglan.Animate.prototype.pause=function(){
	if(!this._data.isPlay){return false;}
	this._data.ispush = true;
	clearInterval(this.interval);
	this._data.isPlay = false;
	this.listener.notify('pause');
};
/**
 * 动画继续
 * 该方法是使暂停的动画继续渲染
 * 
 * @function
 * @public 
 */
qinglan.Animate.prototype.restart=function(){
	if(this._data.isPlay){return false;}
	this._data.ispush = false;
	this.init();
	this.listener.notify('restart');
	this.play();
};
/**
 * 设置监听对象
 * @param {qinglan.Listener} listener 监听对象
 * 					支持监听类型方法 finish play pause restart
 * 
 * @function
 * @public
 */
qinglan.Animate.prototype.setListener = function (listener){
	this.listener = listener;
};
/**
 * 动画状态改变函数
 * @param {qinglan.Animate} animate 动画实力
 * @param {Object} styleMap 样式列表
 * @param {Function} callback 回调函数
 * 
 * @function
 * @private
 * @return {Interval} 时间戳对象
 */
qinglan.Animate.prototype._change=function(animate,styleMap,callback) {
	var st = (new Date()).getTime();
	var ele = animate.ele;
	var d  = animate.duration;
	var c = animate._data.sub;
	var b = animate._data.begin;
	var interval = setInterval(function() {
		var t = animate._data.nowTime = new Date().getTime() - st;
		if (t > d){
			callback();
			clearInterval(interval);
			return true;
		}
		var styleCurrentMap = {};
		for (var s in styleMap) {
			styleCurrentMap [s] = animate.equal(t,b[s],c[s],d) + styleMap[s].px ;
		}
		qinglan.Css.set(ele,styleCurrentMap);
		return false;
	}, 20);
	return interval;
};
